﻿using System;
using System.Linq;
using System.Collections.Generic;
using System.ComponentModel;
using System.Data;
using System.Drawing;
using System.Text;
using System.Windows.Forms;
using SegIdenMovil.Entidad;
using GS1.Library;
using SegIdenMovil.Herramientas;
using SegIdenMovil.Delegate;

namespace SegIdenMovil
{
    public partial class frmPrestamo : Form
    {
        #region --- Variables y Constantes ---
        private Cliente clienteSeleccionado = null;
        public Prestamo prestamo { get; set; }

        #endregion

        #region --- Constructor ---
        public frmPrestamo()
        {
            InitializeComponent();
        }
        #endregion

        #region --- Evento Formulario ---
        private void frmPrestamo_Load(object sender, EventArgs e)
        {
            cargarFormulario();
        }

        private void btnBuscarCliente_Click(object sender, EventArgs e)
        {
            elegirCliente();
        }

        private void mnuSalir_Click(object sender, EventArgs e)
        {
            salir(DialogResult.Cancel);
        }

        private void mnuContinuar_Click(object sender, EventArgs e)
        {
            continuar();
        }

        private void txtClienteNroDocumento_KeyDown(object sender, KeyEventArgs e)
        {
            if (e.KeyCode == Keys.Enter) { buscarCliente(); }
        }

        private void txtClienteNroDocumento_TextChanged(object sender, EventArgs e)
        {
            limpiarDatosCliente();
        }
        #endregion

        #region --- Metodos Propios ---
        private void cargarFormulario()
        {
            ListaGeneral listaTipoDocumento = null;

            try
            {
                Cursor.Current = Cursors.WaitCursor;
                this.WindowState = FormWindowState.Maximized;

                // Mostrar descripcion de tienda
                this.lblEtiquetaTienda.Text = ParametrosAplicacion.TIENDA_ACTUAL.descripcion;

                // Instanciando y creando listado de documentos
                listaTipoDocumento = new ListaGeneral();
                listaTipoDocumento.Add(new General { codigo = Constantes.CODIGO_TIPO_DOCUMENTO_DNI, descripcion = Constantes.DESCRIPCION_TIPO_DOCUMENTO_DNI });
                listaTipoDocumento.Add(new General { codigo = Constantes.CODIGO_TIPO_DOCUMENTO_RUC, descripcion = Constantes.DESCRIPCION_TIPO_DOCUMENTO_RUC });
                listaTipoDocumento.Add(new General { codigo = Constantes.CODIGO_TIPO_DOCUMENTO_CE, descripcion = Constantes.DESCRIPCION_TIPO_DOCUMENTO_CE });
                listaTipoDocumento.Add(new General { codigo = Constantes.CODIGO_TIPO_DOCUMENTO_CI, descripcion = Constantes.DESCRIPCION_TIPO_DOCUMENTO_CI });

                // Estableciendo parametros del combo Tipo documento
                this.cboTipoDocumento.DataSource = listaTipoDocumento;
                this.cboTipoDocumento.ValueMember = Constantes.GENERAL_CODIGO;
                this.cboTipoDocumento.DisplayMember = Constantes.GENERAL_DESCRIPCION;
                this.cboTipoDocumento.SelectedIndex = 0;

                this.dtpFechaInicio.Value = DateTime.Now;
                this.dtpFechaFin.Value = DateTime.Now;
            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void elegirCliente()
        {
            using (frmListado frmListado = new frmListado())
            {
                frmListado.TipoListado = frmListado.TipoLista.CLIENTE;
                if (frmListado.ShowDialog() == DialogResult.Cancel) { frmListado.Dispose(); return; }

                this.clienteSeleccionado = (Cliente)frmListado.ItemSeleccionado;
                this.cboTipoDocumento.SelectedValue = this.clienteSeleccionado.tipoDocumento;
                this.txtClienteNroDocumento.Text = this.clienteSeleccionado.nroDocumento;
                this.txtClienteRazonSocial.Text = this.clienteSeleccionado.razonSocial;
                frmListado.Dispose();
            }
        }

        private bool validarEntradaBusqueda()
        {
            this.txtClienteNroDocumento.Text = this.txtClienteNroDocumento.Text.Trim();

            if (this.txtClienteNroDocumento.Text.Equals(string.Empty))
            {
                Util.CampoNecesario(this.txtClienteNroDocumento, "Debes ingresa el número de documento", this.Text);
                return true;
            }

            if (this.txtClienteNroDocumento.TextLength < 3)
            {
                Util.CampoNecesario(this.txtClienteNroDocumento, "Debe ingresar por lo menos 3 caracteres para realizar la busqueda", this.Text);
                return true;
            }

            return false;
        }

        private void buscarCliente()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                if (validarEntradaBusqueda()) { return; }

                Cursor.Current = Cursors.WaitCursor;

                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_OBTENER_CLIENTE_PORDOCUMENTO;

                operacion.cliente = new Cliente();
                operacion.cliente.tipoDocumento = this.cboTipoDocumento.SelectedValue.ToString();
                operacion.cliente.nroDocumento = this.txtClienteNroDocumento.Text;

                // Instanciando y ejecutando llamada al ServicioREST
                using (ConexionREST conexionREST = new ConexionREST())
                {
                    contenidoXML = conexionREST.ejecutarOperacion(operacion);
                }

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Util.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                // Obteniendo Objeto de Cliente
                Cliente cliente = contenidoXML.DeserializarTo<Cliente>();

                // Limpiando datos del cliente anterior
                limpiarDatosCliente();

                // Si el cliente existe
                if (cliente != null)
                {
                    if (cliente.estado.Equals(Constantes.ESTADO_CODIGO_INACTIVO))
                    {
                        Util.ShowMessageboxExclamacion("Este cliente se encuentra en estado inactivo", this.Text);
                        return;
                    }

                    // Establecer su razon social
                    this.clienteSeleccionado = cliente;
                    this.txtClienteRazonSocial.Text = clienteSeleccionado.razonSocial;
                }
                else
                {
                    Util.ShowMessageboxExclamacion("El cliente buscado no existe", this.Text);
                    return;
                }
            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private bool validarEntrada()
        {
            this.txtClienteRazonSocial.Text = this.txtClienteRazonSocial.Text.Trim();

            if (this.txtClienteRazonSocial.Text.Equals(string.Empty))
            {
                Util.CampoNecesario(this.txtClienteNroDocumento, "Debes seleccionar o buscar el cliente", this.Text);
                return true;
            }

            if (this.dtpFechaInicio.Value > this.dtpFechaFin.Value)
            {
                Util.CampoNecesario(this.dtpFechaInicio, "La fecha de inicio del prestamo no puede ser mayor a la fecha fin", this.Text);
                return true;
            }

            return false;
        }

        private void limpiarDatosCliente()
        {
            // Limpiando datos del cliente anterior
            this.txtClienteRazonSocial.Text = string.Empty;
        }

        private void continuar()
        {
            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                if (validarEntrada()) { return; }

                if (!Util.ShowMessageboxPregunta("¿Esta seguro de guardar el prestamo?")) { return; }

                // Estableciendo cliente
                prestamo.cliente = new Cliente();
                prestamo.cliente.codCliente = this.clienteSeleccionado.codCliente;

                prestamo.tienda = new Tienda();
                prestamo.tienda = ParametrosAplicacion.TIENDA_ACTUAL;

                prestamo.periodoxDias = (this.dtpFechaFin.Value - this.dtpFechaInicio.Value).Days.ToString();
                prestamo.fechaInicio = this.dtpFechaInicio.Value.ToString(Constantes.FORMATO_FECHAHORA);
                prestamo.fechaFin = this.dtpFechaFin.Value.ToString(Constantes.FORMATO_FECHAHORA);

                // Estableciendo usuario de registro
                prestamo.usuario = new Usuario();
                prestamo.usuario.codUsuario = ParametrosAplicacion.USUARIO_ACTUAL.codUsuario;

                // Estableciendo estado y fecha
                prestamo.estado = Constantes.ESTADO_DOCUMENTO_PENDIENTE;
                prestamo.fechaRegistro = DateTime.Now.ToString(Constantes.FORMATO_FECHAHORA);

                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_REGISTRAR_PRESTAMO;

                operacion.prestamo = this.prestamo;
                
                // Instanciando y ejecutando llamada al ServicioREST
                using (ConexionREST conexionREST = new ConexionREST())
                {
                    contenidoXML = conexionREST.ejecutarOperacion(operacion);
                }

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Util.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                OperacionResultado operacionResultado = contenidoXML.DeserializarTo<OperacionResultado>();

                if ((operacionResultado != null) &&
                    (operacionResultado.esOK.Equals(Constantes.SI)))
                {
                    this.prestamo.codPrestamo = operacionResultado.codigoGenerado;
                    Util.ShowMessageboxInfo("Prestamo guardado correctamente");
                }
                else
                {
                    Util.ShowMessageboxError("No se guardo los datos");
                    return;
                }

                validarGuia();


            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
        }

        private void validarGuia()
        {
            if (!Util.ShowMessageboxPregunta("¿Se van a retirar los productos ahora?")) { return; }

            //llama a la pantalla para capturar los datos de la guia
            Guia guia = null;

            using (frmDespGuia frmDespGuia = new frmDespGuia())
            {
                frmDespGuia.prestamo = this.prestamo;
                frmDespGuia.esPrestamo = true;
                frmDespGuia.ShowDialog();
                guia = frmDespGuia.guiaPrestamo;
                frmDespGuia.Dispose();
            }

            //Temporalmente le asigna un código 0 que en Java se actualiza
            guia.codGuia = Constantes.VALOR_CERO;
            //Se considera que el bien vendido ha sido DESPACHADO
            guia.estado = Constantes.ESTADO_DOCUMENTO_DESPACHADO;
            //Se toma la fecha y hora de manera temporal como fecha de emisión
            guia.fechaEmision = DateTime.Now.ToString(Constantes.FORMATO_FECHAHORA);
            //Se toma la fecha y hora de manera temporal como fecha de registro
            guia.fechaRegistro = DateTime.Now.ToString(Constantes.FORMATO_FECHAHORA);
            //Se cambia el estado del prestamo
            this.prestamo.estado = Constantes.ESTADO_DOCUMENTO_DESPACHADO;
            //Se le asigna el prestamo
            guia.prestamo = this.prestamo;
            //Se crean las lineas de la guia
            ListaLineaGuia listaLineaGuia = new ListaLineaGuia();
            //se abre el contenido de la Venta, por que se cargaran todas las lineas en la guia
            
             foreach (Item item in this.prestamo.listaItem.lista)
             {
                 //la variable iNumeroLinea es una numeración de linea temporal
                 int iNumeroLinea = 1;
                 Boolean bLineaNueva = true;
                 foreach (LineaGuia lineaGuia in listaLineaGuia.lista)
                 {
                     if (lineaGuia.producto.codigo.Equals(item.producto.codigo))
                     {
                         lineaGuia.cantidad = (Convert.ToInt32(lineaGuia.cantidad) + 1).ToString();
                         
                         LineaGuiaItem lineaGuiaItem = new LineaGuiaItem();
                         lineaGuiaItem.codGuia = Constantes.VALOR_CERO;
                         lineaGuiaItem.nroLinea = lineaGuia.numeroLinea;
                         lineaGuiaItem.item = item;

                         lineaGuia.listaLineaGuiaItem.add(lineaGuiaItem);

                         bLineaNueva = false;
                     }
                     //Se suma una linea nueva
                     iNumeroLinea++;
                 }

                 if (bLineaNueva)
                 {
                     LineaGuia lineaGuia = new LineaGuia();
                     lineaGuia.cantidad = Constantes.VALOR_UNO;
                     lineaGuia.codGuia = Constantes.VALOR_CERO;
                     lineaGuia.numeroLinea = iNumeroLinea.ToString();
                     lineaGuia.producto = item.producto;

                     LineaGuiaItem lineaGuiaItem = new LineaGuiaItem();
                     lineaGuiaItem.codGuia = Constantes.VALOR_CERO;
                     lineaGuiaItem.nroLinea = iNumeroLinea.ToString();
                     lineaGuiaItem.item = item;
                     lineaGuiaItem.item.tienda = new Tienda();
                     lineaGuiaItem.item.tienda = ParametrosAplicacion.TIENDA_ACTUAL;

                     lineaGuia.listaLineaGuiaItem = new ListaLineaGuiaItem();
                     lineaGuia.listaLineaGuiaItem.add(lineaGuiaItem);

                     listaLineaGuia.add(lineaGuia);
                 }
             }
            //La guia esta llena
            guia.listaLineaGuia = listaLineaGuia;

            Operacion operacion = null;
            string contenidoXML = string.Empty;

            try
            {
                Cursor.Current = Cursors.WaitCursor;

                // Estableciendo operacion a ser enviada al Servicio REST
                operacion = new Operacion();
                operacion.numero = Constantes.OPERACION_REGISTRAR_GUIA_DOCUMENTO;

                operacion.guia = guia;

                // Instanciando y ejecutando llamada al ServicioREST
                using (ConexionREST conexionREST = new ConexionREST())
                {
                    contenidoXML = conexionREST.ejecutarOperacion(operacion);
                }

                // Obteniendo Objeto de Error
                OperacionError operacionError = contenidoXML.DeserializarTo<OperacionError>();

                // Validar si hay error
                if (operacionError != null)
                {
                    Util.ShowMessageboxError(operacionError.descripcion);
                    return;
                }

                OperacionResultado operacionResultado = contenidoXML.DeserializarTo<OperacionResultado>();

                if ((operacionResultado != null) &&
                    (operacionResultado.esOK.Equals(Constantes.SI)))
                {
                    Util.ShowMessageboxInfo("Guia guardado correctamente");

                }
                else
                {
                    Util.ShowMessageboxError("No se guardo los datos");
                    return;
                }

                salir(DialogResult.OK);
            }
            catch (Exception ex)
            {
                Util.MensajeError(ex, this.Text);
            }
            finally
            {
                Cursor.Current = Cursors.Default;
            }
    
        
        }
        private void salir(DialogResult resultado)
        {
            this.DialogResult = resultado;
        }
        #endregion
    }
}